﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Linq;
using Caliburn.Micro;
using Example.Entities;
using Example.Transports.Customer;
using Zero.Common;
using Zero.Frontend;

namespace Example.Frontend.Customers
{
    [Export]
    public class CustomersViewModel : Conductor<IChild>.Collection.OneActive
    {
        [ImportingConstructor]
        public CustomersViewModel(CustomerInfoViewModel info, CustomerOrdersViewModel orders)
        {
            _info = info;
            _orders = orders;

            Customers = new ObservableCollection<Customer>();
        }

        private readonly CustomerInfoViewModel _info;
        private readonly CustomerOrdersViewModel _orders;

        protected override void OnInitialize()
        {
            base.OnInitialize();

            DisplayName = "Customers";

            Items.Add(_info);
            Items.Add(_orders);

            ReloadCustomers();
        }

        public ObservableCollection<Customer> Customers { get; private set; }

        private Customer _selectedCustomer;
        public Customer SelectedCustomer
        {
            get
            {
                return _selectedCustomer;
            }
            set
            {
                if (_selectedCustomer == value)
                {
                    return;
                }

                _selectedCustomer = value;

                _info.Customer = _selectedCustomer;
                _orders.Customer = _selectedCustomer;

                NotifyOfPropertyChange(() => SelectedCustomer);
                NotifyOfPropertyChange(() => CanEditCustomer);
                NotifyOfPropertyChange(() => CanDeleteCustomer);
            }
        }

        public void ReloadCustomers(int? selectCustomerID = null)
        {
            Coroutine.BeginExecute(LoadCustomers(selectCustomerID).GetEnumerator(), new ActionExecutionContext { Target = this });
        }

        private IEnumerable<IResult> LoadCustomers(int? selectCustomerID = null)
        {
            yield return Show.Busy();

            if (selectCustomerID == null & SelectedCustomer != null)
                selectCustomerID = SelectedCustomer.Id;

            var request = new GetCustomers().AsRequest();

            yield return request;

            if (request.Successful)
            {
                Customers.ClearAndAddRange(request.Result.Customers);

                SelectedCustomer = Customers.FirstOrDefault(c => c.Id == selectCustomerID);
            }
            else
            {
                MessageBox.Show(request.Error.ToString(), "Error");
            }

            yield return Show.NotBusy();
        }

        public IEnumerable<IResult> AddCustomer()
        {
            yield return Show.Child<CustomerEditViewModel>()
                .In(Parent)
                .Configured(a => a.AsEditOf(this));
        }

        public IEnumerable<IResult> EditCustomer()
        {
            yield return Show.Child<CustomerEditViewModel>()
                .In(Parent)
                .Configured(a => a.AsEditOf(this, SelectedCustomer.Id));
        }

        public IEnumerable<IResult> DeleteCustomer()
        {
            var result = MessageBox.Show("Do you want to delete selected Customer?", "Confirm delete", MessageBoxButton.YesNo);

            if (result == MessageBoxResult.Yes)
            {
                yield return Show.Busy();
                
                yield return new DeleteCustomer {CustomerID = SelectedCustomer.Id}.AsRequest();

                yield return LoadCustomers().Execute();

                yield return Show.NotBusy();
            }
        }

        public bool CanEditCustomer
        {
            get { return SelectedCustomer != null; }
        }

        public bool CanDeleteCustomer
        {
            get { return SelectedCustomer != null; }
        }
    }
}